﻿namespace Comet.ViewModel
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Comet.Infrastructure;
    using EnvDTE;
    using MvvmFoundation.Wpf;

    public class DataMemberViewModel : ObservableObject
    {
        #region Backing Fields

        DataMemberType dataMemberType;
        DataMemberVisibility dataMemberVisibility;
        bool isSelected;
        string typeName;
        string name;

        #endregion

        #region Fields

        private CodeElement dataMember;

        #endregion

        #region Model

        public CodeElement DataMember
        {
            get { return dataMember; }
        }

        #endregion

        #region Observable Properties

        public bool IsSelected
        {
            get
            {
                return this.isSelected;
            }

            set
            {
                if (this.isSelected == value)
                {
                    return;
                }

                this.isSelected = value;
                RaisePropertyChanged("IsSelected");
            }
        }

        public string TypeName
        {
            get
            {
                return this.typeName;
            }

            set
            {
                if (this.typeName == value)
                {
                    return;
                }

                this.typeName = value;
                RaisePropertyChanged("TypeName");
            }
        }

        public string Name
        {
            get
            {
                return this.name;
            }

            set
            {
                if (this.name == value)
                {
                    return;
                }

                this.name = value;
                RaisePropertyChanged("Name");
            }
        }

        public DataMemberType DataMemberType
        {
            get
            {
                return this.dataMemberType;
            }

            set
            {
                if (this.dataMemberType == value)
                {
                    return;
                }

                this.dataMemberType = value;
                RaisePropertyChanged("DataMemberType");
            }
        }

        public DataMemberVisibility DataMemberVisibility
        {
            get
            {
                return this.dataMemberVisibility;
            }

            set
            {
                if (this.dataMemberVisibility == value)
                {
                    return;
                }

                this.dataMemberVisibility = value;
                RaisePropertyChanged("DataMemberVisibility");
            }
        }

        #endregion

        #region Constructors

        public DataMemberViewModel(CodeElement codeElement)
        {
            if (codeElement == null)
            {
                throw new ArgumentNullException("codeElement");
            }

            if (codeElement is CodeProperty)
            {
                this.dataMemberType = DataMemberType.Property;
                this.dataMemberVisibility = CometUtils.ToDataMemberVisibility(((CodeProperty)this.dataMember).Access);
                this.typeName = ((CodeProperty)this.dataMember).Type.AsString;
            }
            else if (codeElement is CodeVariable)
            {
                this.dataMemberType = DataMemberType.Field;
                this.dataMemberVisibility = CometUtils.ToDataMemberVisibility(((CodeVariable)this.dataMember).Access);
                this.typeName = ((CodeVariable)this.dataMember).Type.AsString;
            }
            else
            {
                throw new ArgumentException("codeElement must be a CodeVariable or a CodeProperty");
            }
            
            this.dataMember = codeElement;
            this.name = codeElement.Name;
        }

        public DataMemberViewModel(CodeProperty codeProperty)
        {
            if (codeProperty == null)
            {
                throw new ArgumentNullException("codeProperty");
            }

            this.dataMember = codeProperty as CodeElement;
            this.dataMemberType = DataMemberType.Property;
            this.dataMemberVisibility = CometUtils.ToDataMemberVisibility(codeProperty.Access);
            this.name = codeProperty.Name;
            this.typeName = codeProperty.Type.AsString;
        }

        public DataMemberViewModel(CodeVariable codeVariable)
        {
            if (codeVariable == null)
            {
                throw new ArgumentNullException("codeVariable");
            }

            this.dataMember = codeVariable as CodeElement;
            this.dataMemberType = DataMemberType.Field;
            this.dataMemberVisibility = CometUtils.ToDataMemberVisibility(codeVariable.Access);
            this.name = codeVariable.Name;
            this.typeName = codeVariable.Type.AsString;
        }
        #endregion
    }
}
